Fix #5946: $this type of static (self, ...) type must remains static#4902
Merged
ondrejmirtes merged 1 commit into2.1.xfrom Feb 12, 2026
Merged
Fix #5946: $this type of static (self, ...) type must remains static#4902ondrejmirtes merged 1 commit into2.1.xfrom
$this type of static (self, ...) type must remains static#4902ondrejmirtes merged 1 commit into2.1.xfrom
Conversation
- In StaticType::transformStaticType(), when the caller is a StaticType (not ThisType) and the method return type is ThisType, downgrade it to StaticType since $this cannot be guaranteed on a static caller - New regression test in tests/PHPStan/Rules/Methods/data/bug-5946.php - The root cause was that ThisType::changeBaseClass() returns a new ThisType, preserving $this semantics even when the caller is only static Fixes phpstan/phpstan#5946
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a method with
@return $thisis called on astaticreturn type, the result type was incorrectly preserved as$thisinstead of being downgraded tostatic. This caused PHPStan to miss reporting a type error when returning the result of such a chain from a method that requires$this.For example:
$this->getParent()returnsstatic(Model), then callinggetModel()on that should yieldstatic(Model)(not$this(Model)), because$thiscannot be guaranteed when the caller is merelystatic.Changes
src/Type/StaticType.php: IntransformStaticType(), afterchangeBaseClass(), check if the resulting type isThisTypeand the caller ($this) is not aThisType— if so, construct a plainStaticTypeinsteadtests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php: AddedtestBug5946()test methodtests/PHPStan/Rules/Methods/data/bug-5946.php: New test data file reproducing the issueCLAUDE.md: Added documentation aboutStaticType::transformStaticTypeandThisTypedowngradingRoot cause
StaticType::transformStaticType()uses$type->changeBaseClass($classReflection)to transform return types. SinceThisType extends StaticType, both are caught by theinstanceof StaticTypecheck. However,ThisType::changeBaseClass()returns a newThisType(preserving$thissemantics), when it should have been downgraded to a plainStaticTypefor callers that arestaticbut not$this. The fix explicitly checks for this case and constructs aStaticTypeinstead.Test
Added a regression test with a
Modelclass that has agetParent()returningstaticand agetModel()returning$this. The test verifies that both$this->getParent()and$this->getParent()->getModel(false)are correctly reported as returningstatic(Model)instead of$this(Model).Fixes phpstan/phpstan#5946